package responsechain

import (
	"fmt"
)

/*
使用责任链模式 模拟旅客的登机流程
*/

// Passenger 旅客
type Passenger struct {
	name                  string // 姓名
	hasBoardingPass       bool   // 是否办理登机牌 初始化false
	hasLuggage            bool   // 是否有行李需要托运 初始化true
	isPassIdentityCheck   bool   // 是否通过身份校验 初始化false
	isPassSecurityCheck   bool   // 是否通过安检 初始化false
	isCompleteForBoarding bool   // 是否完成登机 初始化false
}

type BaseHandler interface {
	// SetNextHandler 设置下一个处理器
	SetNextHandler(b BaseHandler)
	// ProcessFor 流转流程 因为是嵌套 所以要调用下一个处理器的方法
	ProcessFor(p *Passenger)
}

// Login 办理登机牌
type Login struct {
	NextHandler BaseHandler
}

func (l *Login) SetNextHandler(b BaseHandler) {
	l.NextHandler = b
}

func (l *Login) ProcessFor(p *Passenger) {
	if !p.hasBoardingPass {
		fmt.Println(fmt.Printf("%s%s", p.name, "办理登机牌成功..."))
		p.hasBoardingPass = true
		l.NextHandler.ProcessFor(p)
	}
}

// TransPort 是否有行李需要托运
type TransPort struct {
	NextHandler BaseHandler
}

func (t *TransPort) SetNextHandler(b BaseHandler) {
	t.NextHandler = b
}

func (t *TransPort) ProcessFor(p *Passenger) {
	if p.hasBoardingPass == false {
		fmt.Println("乘客还未办理登机牌")
	}
	if p.hasLuggage {
		fmt.Println(fmt.Printf("%s%s", p.name, "托运成功..."))
		t.NextHandler.ProcessFor(p)
	}
}

// CheckId 是否通过身份校验
type CheckId struct {
	NextHandler BaseHandler
}

func (c *CheckId) SetNextHandler(b BaseHandler) {
	c.NextHandler = b
}

func (c *CheckId) ProcessFor(p *Passenger) {
	if p.hasBoardingPass == false {
		fmt.Println("乘客还未办理登机牌")
	}
	if !p.isPassIdentityCheck {
		fmt.Println(fmt.Printf("%s%s", p.name, "通过身份校验..."))
		p.isPassIdentityCheck = true
		c.NextHandler.ProcessFor(p)
	}
}

// CheckSecurity 是否通过安检
type CheckSecurity struct {
	NextHandler BaseHandler
}

func (c *CheckSecurity) SetNextHandler(b BaseHandler) {
	c.NextHandler = b
}

func (c *CheckSecurity) ProcessFor(p *Passenger) {
	if p.hasBoardingPass == false {
		fmt.Println("乘客还未办理登机牌")
	}
	if p.isPassIdentityCheck == false {
		fmt.Println("乘客还未通过身份校验")
	}
	if !p.isPassSecurityCheck {
		fmt.Println(fmt.Printf("%s%s", p.name, "通过安检..."))
		p.isPassIdentityCheck = true
		c.NextHandler.ProcessFor(p)
	}
}

// Boarding 是否完成登机 打印乘客姓名
type Boarding struct {
	NextHandler BaseHandler
}

func (bo *Boarding) SetNextHandler(b BaseHandler) {
	bo.NextHandler = b
}

func (bo *Boarding) ProcessFor(p *Passenger) {
	if p.hasBoardingPass == false {
		fmt.Println("乘客还未办理登机牌")
	}
	if p.isPassIdentityCheck == false {
		fmt.Println("乘客还未通过身份校验")
	}
	if p.isPassSecurityCheck {
		fmt.Println("乘客还未通过安全校验")
	}
	if !p.isCompleteForBoarding {
		p.isCompleteForBoarding = true
		fmt.Println(fmt.Printf("%s%s", p.name, "已登机..."))
	}
}
